package com.tegtech.starter.redisson;

import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

import javax.annotation.PostConstruct;

import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * redis分布式锁
 * @Author Jun
 * @date 2019年12月26日 上午9:32:52
 */
@Component
public class RedissonLock {

	@Autowired
	private DistributedLocker locker;

	// 静态注入
	private static DistributedLocker distributedLocker;
	
	// 默认超时时间：8秒
	private static final int EXPIRE = 8; 

	@PostConstruct
	private void init() {
		distributedLocker = locker;
	}

	/**
	 * 加锁，非公平锁
	 * @param lockKey
	 * @return
	 */
	public static RLock lock(String lockKey) {
		return distributedLocker.lock(lockKey);
	}

    /**
     * 带超时的锁
     * @param lockKey
     * @param timeout 超时时间   单位：秒
     */
    public static RLock lock(String lockKey, int timeout) {
        return distributedLocker.lock(lockKey, timeout);
    }

    /**
     * 带超时的锁
     * @param lockKey
     * @param unit 时间单位
     * @param timeout 超时时间
     */
    public static RLock lock(String lockKey, int timeout, TimeUnit unit) {
        return distributedLocker.lock(lockKey, unit, timeout);
    }

    /**
	 * 加锁，公平锁/顺序锁
	 * @param lockKey
	 * @return
	 */
	public static RLock fairLock(String lockKey) {
		return distributedLocker.fairLock(lockKey);
	}

    /**
     * 尝试获取锁，默认最多等待5秒，上锁后自动释放锁时间为EXPIRE秒
     * @param lockKey
     * @return
     */
    public static boolean tryLock(String lockKey) {
        return distributedLocker.tryLock(lockKey, TimeUnit.SECONDS, EXPIRE, EXPIRE);
    }

    /**
     * 尝试获取锁
     * @param lockKey
     * @param waitTime 最多等待时间	单位：秒
     * @param leaseTime 上锁后自动释放锁时间		单位：秒
     * @return
     */
    public static boolean tryLock(String lockKey, int waitTime, int leaseTime) {
        return distributedLocker.tryLock(lockKey, TimeUnit.SECONDS, waitTime, leaseTime);
    }

    /**
     * 尝试获取锁
     * @param lockKey
     * @param unit 时间单位
     * @param waitTime 最多等待时间
     * @param leaseTime 上锁后自动释放锁时间
     * @return
     */
    public static boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {
        return distributedLocker.tryLock(lockKey, unit, waitTime, leaseTime);
    }

    /**
     * 释放锁
     * @param lockKey
     */
    public static void unlock(String lockKey) {
        distributedLocker.unlock(lockKey);
    }

    /**
     * 释放锁
     * @param lock
     */
    public static void unlock(RLock lock) {
        distributedLocker.unlock(lock);
    }
    
    /**
     * 带超时的锁，默认超时时间8秒
     * @param lockKey
     * @param function
     */
    public static void lock(String lockKey, NvFuction function) {
    	try {
			lock(lockKey, EXPIRE);
			function.run();
		} finally {
			unlock(lockKey);
		}
    }
    
    /**
     * 带超时的锁，默认超时时间8秒
     * @param <R>
     * @param lockKey
     * @param supplier
     * @return
     */
	public static <R> R lock(String lockKey, Supplier<R> supplier) {
		try {
			lock(lockKey, EXPIRE);
			return supplier.get();
		} finally {
			unlock(lockKey);
		}
	}

}
